home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -serious- / programming / other / dopus412-gpl / dopus_disk / diskop.c < prev    next >
C/C++ Source or Header  |  2000-02-28  |  18KB  |  766 lines

  1. /*
  2.  
  3. Directory Opus 4
  4. Original GPL release version 4.12
  5. Copyright 1993-2000 Jonathan Potter
  6.  
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. as published by the Free Software Foundation; either version 2
  10. of the License, or (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. All users of Directory Opus 4 (including versions distributed
  22. under the GPL) are entitled to upgrade to the latest version of
  23. Directory Opus version 5 at a reduced price. Please see
  24. http://www.gpsoft.com.au for more information.
  25.  
  26. The release of Directory Opus 4 under the GPL in NO WAY affects
  27. the existing commercial status of Directory Opus 5.
  28.  
  29. */
  30.  
  31. #include "diskop.h"
  32.  
  33. void main(argc,argv)
  34. int argc;
  35. char *argv[];
  36. {
  37.     struct DOpusRemember *memkey=NULL;
  38.     struct VisInfo *vis;
  39.     char **dummy_args,*port,*opbuf,*stringname;
  40.     struct StringData *stringdata;
  41.     int arg;
  42.  
  43.     if (!(DOpusBase=(struct DOpusBase *)OpenLibrary("dopus.library",18)))
  44. #ifdef __SASC_60
  45.         __exit(0);
  46. #else
  47.         _exit(0);
  48. #endif
  49.  
  50.     if ((vis=LAllocRemember(&memkey,sizeof(struct VisInfo),MEMF_CLEAR)) &&
  51.         (dummy_args=LAllocRemember(&memkey,sizeof(char *)*16,MEMF_CLEAR)) &&
  52.         (opbuf=LAllocRemember(&memkey,80,MEMF_CLEAR)) &&
  53.         (stringname=LAllocRemember(&memkey,80,MEMF_CLEAR)) &&
  54.         (stringdata=LAllocRemember(&memkey,sizeof(struct StringData),MEMF_CLEAR))) {
  55.  
  56.         IntuitionBase=DOpusBase->IntuitionBase;
  57.         GfxBase=DOpusBase->GfxBase;
  58.         IconBase=OpenLibrary("icon.library",0);
  59.  
  60.         if (argc==0) {
  61.             struct WBStartup *startup;
  62.             int arg;
  63.  
  64.             startup=(struct WBStartup *)argv;
  65.             for (arg=0;arg<startup->sm_NumArgs && arg<16;arg++) {
  66.                 dummy_args[arg]=startup->sm_ArgList[arg].wa_Name;
  67.                 ++argc;
  68.             }
  69.             argv=dummy_args;
  70.  
  71.             if (IconBase) {
  72.                 struct DiskObject *dobj;
  73.                 char *str;
  74.  
  75.                 if (dobj=GetDiskObject(argv[0])) {
  76.                     if (str=FindToolType(dobj->do_ToolTypes,"OPERATION")) {
  77.                         LStrnCpy(opbuf,str,80);
  78.                         argv[1]=opbuf;
  79.                         if (argc<2) argc=2;
  80.                     }
  81.                     FreeDiskObject(dobj);
  82.                 }
  83.             }
  84.         }
  85.  
  86.         if (argc>1) {
  87.             if (argc>2 && argv[2][0]=='&') {
  88.                 arg=3;
  89.                 port=&argv[2][1];
  90.             }
  91.             else {
  92.                 arg=2;
  93.                 port=NULL;
  94.             }
  95.             get_vis_info(vis,port);
  96.  
  97.             stringdata->default_table=default_strings;
  98.             stringdata->string_count=STR_STRING_COUNT;
  99.             stringdata->min_version=STRING_VERSION;
  100.  
  101.             if (vis->vi_language)
  102.                 lsprintf(stringname,"DOpus:Modules/S/DM_Disk_%s.STR",vis->vi_language);
  103.             else stringname[0]=0;
  104.  
  105.             if (ReadStringFile(stringdata,stringname)) {
  106.                 string_table=stringdata->string_table;
  107.  
  108.                 switch (argv[1][0]) {
  109.                     case 'f':
  110.                     case 'F':
  111.                         diskop_format(vis,port,argc-arg,&argv[arg]);
  112.                         break;
  113.                     case 'd':
  114.                     case 'D':
  115.                         diskop_diskcopy(vis,port,argc-arg,&argv[arg]);
  116.                         break;
  117.                     case 'i':
  118.                     case 'I':
  119.                         diskop_install(vis,argc-arg,&argv[arg]);
  120.                         break;
  121.                 }
  122.             }
  123.             FreeStringFile(stringdata);
  124.         }
  125.  
  126.         if (IconBase) CloseLibrary(IconBase);
  127.     }
  128.  
  129.     LFreeRemember(&memkey);
  130.  
  131.     CloseLibrary((struct Library *)DOpusBase);
  132. #ifdef __SASC_60
  133.     __exit(0);
  134. #else
  135.     _exit(0);
  136. #endif
  137. }
  138.  
  139. void get_vis_info(vis,portname)
  140. struct VisInfo *vis;
  141. char *portname;
  142. {
  143.     vis->vi_fg=1; vis->vi_bg=0;
  144.     vis->vi_shine=2; vis->vi_shadow=1;
  145.     vis->vi_font=NULL;
  146.     vis->vi_screen=NULL;
  147.     vis->vi_stringcol[0]=1; vis->vi_stringcol[1]=0;
  148.     vis->vi_activestringcol[0]=1; vis->vi_activestringcol[1]=0;
  149.     vis->vi_flags=VISF_WINDOW;
  150.     vis->vi_language=NULL;
  151.  
  152.     if (dopus_message(DOPUSMSG_GETVIS,(APTR)vis,portname)) return;
  153.  
  154.     if (IntuitionBase->LibNode.lib_Version>35) {
  155.         struct DrawInfo *drinfo;
  156.         struct Screen *pub;
  157.  
  158.         if (pub=LockPubScreen(NULL)) {
  159.             drinfo=GetScreenDrawInfo(pub);
  160.             vis->vi_shine=drinfo->dri_Pens[SHINEPEN];
  161.             vis->vi_shadow=drinfo->dri_Pens[SHADOWPEN];
  162.             vis->vi_fg=drinfo->dri_Pens[TEXTPEN];
  163.             vis->vi_bg=drinfo->dri_Pens[BACKGROUNDPEN];
  164.             FreeScreenDrawInfo(pub,drinfo);
  165.             UnlockPubScreen(NULL,pub);
  166.         }
  167.     }
  168. }
  169.  
  170. dopus_message(cmd,data,portname)
  171. int cmd;
  172. APTR data;
  173. char *portname;
  174. {
  175.     struct MsgPort *port,*replyport;
  176.     struct DOpusMessage msg;
  177.  
  178.     Forbid();
  179.     if (portname && portname[0] &&
  180.         (port=FindPort(portname)) &&
  181.         (replyport=LCreatePort(NULL,0))) {
  182.         msg.msg.mn_Node.ln_Type=NT_MESSAGE;
  183.         msg.msg.mn_Node.ln_Name=NULL;
  184.         msg.msg.mn_ReplyPort=replyport;
  185.         msg.msg.mn_Length=(UWORD)sizeof(struct DOpusMessage);
  186.         msg.command=cmd;
  187.         msg.data=data;
  188.         PutMsg(port,(struct Message *)&msg);
  189.         Permit();
  190.         WaitPort(replyport);
  191.         GetMsg(replyport);
  192.         LDeletePort(replyport);
  193.         return(1);
  194.     }
  195.     Permit();
  196.     return(0);
  197. }
  198.  
  199. void fill_out_req(req,vis)
  200. struct RequesterBase *req;
  201. struct VisInfo *vis;
  202. {
  203.     req->rb_fg=vis->vi_fg;
  204.     req->rb_bg=vis->vi_bg;
  205.     req->rb_shine=vis->vi_shine;
  206.     req->rb_shadow=vis->vi_shadow;
  207.     req->rb_font=vis->vi_font;
  208.     req->rb_flags&=~RBF_WINDOWCENTER;
  209.     if (vis->vi_screen) {
  210.         if (vis->vi_flags&VISF_WINDOW) {
  211.             req->rb_screen=((struct Window *)vis->vi_screen)->WScreen;
  212.             req->rb_window=(struct Window *)vis->vi_screen;
  213.             req->rb_flags|=RBF_WINDOWCENTER;
  214.         }
  215.         else req->rb_screen=vis->vi_screen;
  216.     }
  217.     else req->rb_screen=NULL;
  218. }
  219.  
  220. struct Gadget *addreqgadgets(reqbase,gadgets,mask,count)
  221. struct RequesterBase *reqbase;
  222. struct TagItem **gadgets;
  223. int mask,*count;
  224. {
  225.     int gad;
  226.     struct Gadget *gadget=NULL,*newgadget,*firstgadget;
  227.  
  228.     for (gad=0;;gad++) {
  229.         if (!gadgets[gad]) break;
  230.         if (!(mask&(1<<gad))) {
  231.             if (!(newgadget=(struct Gadget *)
  232.                 AddRequesterObject(reqbase,gadgets[gad]))) return(NULL);
  233.             if (gadget) gadget->NextGadget=newgadget;
  234.             else firstgadget=newgadget;
  235.             gadget=newgadget;
  236.             ++*count;
  237.         }
  238.     }
  239.     AddGadgets(reqbase->rb_window,firstgadget,NULL,gad,reqbase->rb_shine,reqbase->rb_shadow,1);
  240.     return(firstgadget);
  241. }
  242.  
  243. int error_rets[]={1,0};
  244.  
  245. check_error(reqbase,str,gadtxt)
  246. struct RequesterBase *reqbase;
  247. char *str;
  248. int gadtxt;
  249. {
  250.     struct DOpusSimpleRequest req;
  251.     char *error_gads[3];
  252.  
  253.     req.text=str;
  254.     error_gads[0]=string_table[gadtxt];
  255.     error_gads[1]=string_table[STR_CANCEL];
  256.     error_gads[2]=NULL;
  257.     req.gads=error_gads;
  258.     req.rets=error_rets;
  259.     req.hi=reqbase->rb_shine;
  260.     req.lo=reqbase->rb_shadow;
  261.     req.fg=reqbase->rb_fg;
  262.     req.bg=reqbase->rb_bg;
  263.     req.strbuf=NULL;
  264.     req.flags=SRF_RECESSHI;
  265.     if (reqbase->rb_flags&RBF_BORDERS) req.flags|=SRF_BORDERS;
  266.     req.font=reqbase->rb_font;
  267.     req.title="DOpus_Disk";
  268.     return(DoSimpleRequest(reqbase->rb_window,&req));
  269. }
  270.  
  271. ULONG do_checksum(sector)
  272. ULONG *sector;
  273. {
  274.     ULONG sum;
  275.     int i;
  276.  
  277.     for (sum=0,i=0;i<(TD_SECTOR>>2);i++) sum+=sector[i];
  278.     return(sum);
  279. }
  280.  
  281. do_writeblock(device_req,buffer,offset)
  282. struct IOExtTD *device_req;
  283. APTR buffer;
  284. ULONG offset;
  285. {
  286.     device_req->iotd_Req.io_Command=CMD_WRITE;
  287.     device_req->iotd_Req.io_Data=buffer;
  288.     device_req->iotd_Req.io_Length=TD_SECTOR;
  289.     device_req->iotd_Req.io_Offset=offset*TD_SECTOR;
  290.     return((int)DoIO((struct IORequest *)device_req));
  291. }
  292.  
  293. void inhibit_drive(device,state)
  294. char *device;
  295. ULONG state;
  296. {
  297.     struct MsgPort *handler;
  298.  
  299.     if (DOSBase->dl_lib.lib_Version<36) {
  300.         if (handler=(struct MsgPort *)DeviceProc(device))
  301.             SendPacket(handler,ACTION_INHIBIT,&state,1);
  302.     }
  303.     else Inhibit(device,state);
  304. }
  305.  
  306. void border_text(reqbase,border,infobuf)
  307. struct RequesterBase *reqbase;
  308. Object_Border *border;
  309. char *infobuf;
  310. {
  311.     struct RastPort *rp;
  312.  
  313.     rp=reqbase->rb_window->RPort;
  314.     SetAPen(rp,reqbase->rb_bg);
  315.     RectFill(rp,border->ob_left,border->ob_top,
  316.         border->ob_left+border->ob_width-1,border->ob_top+border->ob_height-1);
  317.     SetAPen(rp,reqbase->rb_fg);
  318.  
  319.     if (infobuf) {
  320.         ObjectText(reqbase,
  321.             border->ob_left,
  322.             border->ob_top,
  323.             border->ob_width,
  324.             border->ob_height,
  325.             infobuf,
  326.             TEXTPOS_CENTER|TEXTPOS_F_NOUSCORE);
  327.     }
  328. }
  329.  
  330. struct DeviceNode *find_device(name)
  331. char *name;
  332. {
  333.     struct RootNode *rootnode;
  334.     struct DosInfo *dosinfo;
  335.     struct DeviceNode *devnode;
  336.     char matchname[32],devname[32];
  337.     int a;
  338.  
  339.     if (!name) return(NULL);
  340.  
  341.     for (a=0;name[a];a++) {
  342.         if (name[a]==':') break;
  343.         matchname[a]=name[a];
  344.     }
  345.     matchname[a]=0;
  346.  
  347.     Forbid();
  348.  
  349.     rootnode=(struct RootNode *) DOSBase->dl_Root;
  350.     dosinfo=(struct DosInfo *) BADDR(rootnode->rn_Info);
  351.     devnode=(struct DeviceNode *) BADDR(dosinfo->di_DevInfo);
  352.  
  353.     while (devnode) {
  354.         if (devnode->dn_Type==DLT_DEVICE && devnode->dn_Task) {
  355.             BtoCStr((BPTR)devnode->dn_Name,devname,32);
  356.             if (strcmp(devname,matchname)==0) {
  357.                 Permit();
  358.                 return(devnode);
  359.             }
  360.         }
  361.         devnode=(struct DeviceNode *) BADDR(devnode->dn_Next);
  362.     }
  363.  
  364.     Permit();
  365.     return(NULL);
  366. }
  367.  
  368. char **get_device_list(key,alike)
  369. struct DOpusRemember **key;
  370. char *alike;
  371. {
  372.     struct RootNode *rootnode;
  373.     struct DosInfo *dosinfo;
  374.     struct DeviceNode *devnode,*alikenode=NULL;
  375.     int count=1;
  376.     char **listtable,devname[32];
  377.  
  378.     if (alike) alikenode=find_device(alike);
  379.  
  380.     Forbid();
  381.  
  382.     rootnode=(struct RootNode *) DOSBase->dl_Root;
  383.     dosinfo=(struct DosInfo *) BADDR(rootnode->rn_Info);
  384.     devnode=(struct DeviceNode *) BADDR(dosinfo->di_DevInfo);
  385.  
  386.     while (devnode) {
  387.         if (devnode->dn_Type==DLT_DEVICE && devnode->dn_Task &&
  388.             devnode->dn_Startup>512) {
  389.             if (!alikenode || like_devices(devnode,alikenode))
  390.                 ++count;
  391.         }
  392.         devnode=(struct DeviceNode *) BADDR(devnode->dn_Next);
  393.     }
  394.  
  395.     if (listtable=LAllocRemember(key,count*4,MEMF_CLEAR)) {
  396.         devnode=(struct DeviceNode *) BADDR(dosinfo->di_DevInfo);
  397.         count=0;
  398.         while (devnode) {
  399.             if (devnode->dn_Type==DLT_DEVICE && devnode->dn_Task &&
  400.                 devnode->dn_Startup>512) {
  401.                 if (!alikenode || like_devices(devnode,alikenode)) {
  402.                     BtoCStr((BPTR)devnode->dn_Name,devname,32);
  403.                     strcat(devname,":");
  404.                     if (listtable[count]=LAllocRemember(key,strlen(devname)+1,0))
  405.                         strcpy(listtable[count],devname);
  406.                     ++count;
  407.                 }
  408.             }
  409.             devnode=(struct DeviceNode *) BADDR(devnode->dn_Next);
  410.         }
  411.         sort_device_list(listtable);
  412.     }
  413.  
  414.     Permit();
  415.     return(listtable);
  416. }
  417.  
  418. void sort_device_list(table)
  419. char **table;
  420. {
  421.     int count,gap,i,j;
  422.     char *temp;
  423.  
  424.     for (count=0;table[count];count++);
  425.  
  426.     for (gap=count/2;gap>0;gap/=2)
  427.         for (i=gap;i<count;i++)
  428.             for (j=i-gap;j>=0;j-=gap) {
  429.                 if (LStrCmpI(table[j],table[j+gap])<=0) break;
  430.                 temp=table[j];
  431.                 table[j]=table[j+gap];
  432.                 table[j+gap]=temp;
  433.             }
  434. }
  435.  
  436. check_disk(reqbase,device_req,name,prot)
  437. struct RequesterBase *reqbase;
  438. struct IOExtTD *device_req;
  439. char *name;
  440. int prot;
  441. {
  442.     char errorbuf[80];
  443.  
  444.     FOREVER {
  445.         device_req->iotd_Req.io_Command=TD_CHANGESTATE;
  446.         DoIO((struct IORequest *)device_req);
  447.         if (device_req->iotd_Req.io_Actual) {
  448.             lsprintf(errorbuf,string_table[STR_NODISKPRESENT],name);
  449.             if (!(check_error(reqbase,errorbuf,STR_RETRY))) return(0);
  450.         }
  451.         else break;
  452.     }
  453.     if (prot) {
  454.         FOREVER {
  455.             device_req->iotd_Req.io_Command=TD_PROTSTATUS;
  456.             DoIO((struct IORequest *)device_req);
  457.             if (device_req->iotd_Req.io_Actual) {
  458.                 lsprintf(errorbuf,string_table[STR_DISKWRITEPROTECTED],name);
  459.                 if (!(check_error(reqbase,errorbuf,STR_RETRY))) return(0);
  460.             }
  461.             else break;
  462.         }
  463.     }
  464.     return(1);
  465. }
  466.  
  467. check_abort(window)
  468. struct Window *window;
  469. {
  470.     struct IntuiMessage *msg;
  471.     int abort=0;
  472.  
  473.     while (msg=(struct IntuiMessage *)GetMsg(window->UserPort)) {
  474.         if (msg->Class==IDCMP_MOUSEBUTTONS && msg->Code==MENUDOWN)
  475.             abort=1;
  476.         ReplyMsg((struct Message *)msg);
  477.     }
  478.     return(abort);
  479. }
  480.  
  481. check_blank_disk(reqbase,device,action)
  482. struct RequesterBase *reqbase;
  483. char *device,*action;
  484. {
  485.     BPTR lock;
  486.     struct InfoData __aligned info;
  487.     struct FileInfoBlock __aligned fib;
  488.     struct Process *myproc;
  489.     APTR wsave;
  490.     char blank=0,*message,diskname[40],sizebuf[20];
  491.     int ret=1;
  492.  
  493.     if (!(message=AllocMem(400,MEMF_CLEAR))) return(1);
  494.  
  495.     myproc=(struct Process *)FindTask(NULL);
  496.     wsave=myproc->pr_WindowPtr;
  497.     myproc->pr_WindowPtr=(APTR)-1;
  498.  
  499.     if (lock=Lock(device,ACCESS_READ)) {
  500.         Info(lock,&info);
  501.         switch (info.id_DiskType) {
  502.             case ID_UNREADABLE_DISK:
  503.             case ID_NOT_REALLY_DOS:
  504.                 blank=1;
  505.                 break;
  506.             default:
  507.                 Examine(lock,&fib);
  508.                 strcpy(diskname,fib.fib_FileName);
  509.                 if (!(ExNext(lock,&fib))) blank=1;
  510.                 break;
  511.         }
  512.         UnLock(lock);
  513.     }
  514.     else blank=1;
  515.  
  516.     myproc->pr_WindowPtr=wsave;
  517.  
  518.     if (!blank && action) {
  519.         getsizestring(sizebuf,info.id_NumBlocksUsed*info.id_BytesPerBlock);
  520.  
  521.         lsprintf(message,string_table[STR_DISK_NOT_BLANK],
  522.             device,diskname,sizebuf,action);
  523.  
  524.         if (!(check_error(reqbase,message,STR_PROCEED))) ret=0;
  525.     }
  526.     FreeMem(message,400);
  527.     return(ret);
  528. }
  529.  
  530. void set_env(action,gadget,count,list)
  531. char *action;
  532. struct Gadget *gadget;
  533. int count;
  534. struct DOpusListView *list;
  535. {
  536.     int file,listid='LIST';
  537.     UWORD len;
  538.     char envname[80],null=0;
  539.  
  540.     lsprintf(envname,"ENV:DOpus_%s.prefs",action);
  541.     if (!(file=Open(envname,MODE_NEWFILE))) return;
  542.  
  543.     while (gadget && count--) {
  544.         if (gadget->Activation&GACT_TOGGLESELECT) {
  545.             Write(file,&gadget->GadgetID,sizeof(UWORD));
  546.             Write(file,&gadget->GadgetType,sizeof(UWORD));
  547.             switch (gadget->GadgetType) {
  548.                 case GTYP_BOOLGADGET:
  549.                     Write(file,&gadget->Flags,sizeof(UWORD));
  550.                     break;
  551.                 case GTYP_STRGADGET:
  552.                     len=strlen(((struct StringInfo *)gadget->SpecialInfo)->Buffer)+1;
  553.                     Write(file,&len,sizeof(UWORD));
  554.                     Write(file,((struct StringInfo *)gadget->SpecialInfo)->Buffer,len);
  555.                     if (len%2) Write(file,&null,1);
  556.                     break;
  557.             }
  558.         }
  559.         else ++count;
  560.         gadget=gadget->NextGadget;
  561.     }
  562.     while (list) {
  563.         Write(file,&listid,sizeof(ULONG));
  564.         Write(file,list->items[list->itemselected],
  565.             (len=(strlen(list->items[list->itemselected])+1)));
  566.         if (len%2) Write(file,&null,1);
  567.         list=list->next;
  568.     }
  569.     Close(file);
  570. }
  571.  
  572. void get_env(action,firstgadget,count,list)
  573. char *action;
  574. struct Gadget *firstgadget;
  575. int count;
  576. struct DOpusListView *list;
  577. {
  578.     int file,size,a,b,*lbuf;
  579.     char envname[80],*nptr;
  580.     struct Gadget *gadget;
  581.     UWORD gadgettype,gadgetid,len,*buf;
  582.  
  583.     lsprintf(envname,"ENV:DOpus_%s.prefs",action);
  584.     if (!(file=Open(envname,MODE_OLDFILE))) return;
  585.  
  586.     Seek(file,0,OFFSET_END);
  587.     size=Seek(file,0,OFFSET_BEGINNING);
  588.  
  589.     if (!(buf=(UWORD *)AllocMem(size,MEMF_CLEAR))) {
  590.         Close(file);
  591.         return;
  592.     }
  593.  
  594.     Read(file,(char *)buf,size);
  595.     Close(file);
  596.  
  597.     for (a=0;a<size/2;) {
  598.         lbuf=(int *)&buf[a];
  599.         if (lbuf[0]=='LIST') {
  600.             a+=2;
  601.             nptr=(char *)&buf[a];
  602.             if (list) {
  603.                 for (b=0;list->items[b];b++) {
  604.                     if (LStrCmpI(nptr,list->items[b])==0) {
  605.                         list->itemselected=b;
  606.                         break;
  607.                     }
  608.                 }
  609.                 list=list->next;
  610.             }
  611.             b=strlen(nptr)+1;
  612.             if (b%2) ++b;
  613.             a+=b/2;
  614.             continue;
  615.         }
  616.         gadgetid=buf[a++];
  617.         gadgettype=buf[a++];
  618.         gadget=firstgadget;
  619.         while (gadget) {
  620.             if (gadget->GadgetID==gadgetid && gadget->GadgetType==gadgettype)
  621.                 break;
  622.             gadget=gadget->NextGadget;
  623.         }
  624.         if (!count--) gadget=NULL;
  625.         switch (gadgettype) {
  626.             case GTYP_BOOLGADGET:
  627.                 if (gadget) gadget->Flags=buf[a];
  628.                 ++a;
  629.                 break;
  630.             case GTYP_STRGADGET:
  631.                 len=buf[a++];
  632.                 if (gadget) strcpy(((struct StringInfo *)gadget->SpecialInfo)->Buffer,(char *)&buf[a]);
  633.                 if (len%2) ++len;
  634.                 a+=len/2;
  635.                 break;
  636.         }
  637.     }
  638.     FreeMem(buf,size);
  639. }
  640.  
  641. void fix_listview(reqbase,list)
  642. struct RequesterBase *reqbase;
  643. struct DOpusListView *list;
  644. {
  645.     list->window=reqbase->rb_window;
  646.     list->flags|=DLVF_LEAVE|DLVF_SLOW;
  647.     list->sliderwidth=8;
  648.     list->slidercol=reqbase->rb_fg;
  649.     list->sliderbgcol=reqbase->rb_bg;
  650.     list->textcol=reqbase->rb_fg;
  651.     list->boxhi=reqbase->rb_shine;
  652.     list->boxlo=reqbase->rb_shadow;
  653.     list->arrowfg=reqbase->rb_fg;
  654.     list->arrowbg=reqbase->rb_bg;
  655.     list->itemfg=reqbase->rb_fg;
  656.     list->itembg=reqbase->rb_bg;
  657. }
  658.  
  659. void select_device(list,exclude)
  660. struct DOpusListView *list;
  661. char *exclude;
  662. {
  663.     int def=-1,item;
  664.  
  665.     for (item=0;list->items[item];item++) {
  666.         if (!exclude || LStrCmpI(list->items[item],exclude)) {
  667.             if (list->items[item][0]=='D' &&
  668.                 list->items[item][1]=='F' &&
  669.                 list->items[item][3]==':') {
  670.                 def=item;
  671.                 break;
  672.             }
  673.             if (def==-1) def=item;
  674.         }
  675.     }
  676.     if (def==-1) def=0;
  677.     list->itemselected=def;
  678.     list->topitem=def;
  679. }
  680.  
  681. like_devices(node,likenode)
  682. struct DeviceNode *node,*likenode;
  683. {
  684.     struct DosEnvec *envec,*likeenvec;
  685.     struct FileSysStartupMsg *startup,*likestartup;
  686.  
  687.     startup=(struct FileSysStartupMsg *)BADDR(node->dn_Startup);
  688.     likestartup=(struct FileSysStartupMsg *)BADDR(likenode->dn_Startup);
  689.     envec=(struct DosEnvec *)BADDR(startup->fssm_Environ);
  690.     likeenvec=(struct DosEnvec *)BADDR(likestartup->fssm_Environ);
  691.  
  692.     if (envec->de_SizeBlock!=likeenvec->de_SizeBlock ||
  693.         envec->de_Surfaces!=likeenvec->de_Surfaces ||
  694.         envec->de_BlocksPerTrack!=likeenvec->de_BlocksPerTrack ||
  695.         ((envec->de_HighCyl-envec->de_LowCyl))!=
  696.             ((likeenvec->de_HighCyl-likeenvec->de_LowCyl)))
  697.         return(0);
  698.     return(1);
  699. }
  700.  
  701. open_device(device,handle)
  702. char *device;
  703. struct DeviceHandle *handle;
  704. {
  705.     struct DeviceNode *devnode;
  706.     char devicename[40];
  707.  
  708.     handle->startup=NULL;
  709.     handle->dosenvec=NULL;
  710.     handle->device_port=NULL;
  711.     handle->device_req=NULL;
  712.  
  713.     if (!device || !(devnode=find_device(device))) return(0);
  714.  
  715.     handle->startup=(struct FileSysStartupMsg *)BADDR(devnode->dn_Startup);
  716.     handle->dosenvec=(struct DosEnvec *)BADDR(handle->startup->fssm_Environ);
  717.     BtoCStr((BPTR)handle->startup->fssm_Device,devicename,40);
  718.  
  719.     if (!(handle->device_port=LCreatePort(NULL,0))) return(0);
  720.     if (handle->device_req=(struct IOExtTD *)
  721.         LCreateExtIO(handle->device_port,sizeof(struct IOExtTD))) {
  722.         if (!(OpenDevice(devicename,handle->startup->fssm_Unit,
  723.             (struct IORequest *)handle->device_req,handle->startup->fssm_Flags)))
  724.             return(1);
  725.         LDeleteExtIO((struct IORequest *)handle->device_req);
  726.         handle->device_req=NULL;
  727.     }
  728.     return(0);
  729. }
  730.  
  731. void close_device(handle)
  732. struct DeviceHandle *handle;
  733. {
  734.     if (handle->device_req) {
  735.         CloseDevice((struct IORequest *)handle->device_req);
  736.         LDeleteExtIO((struct IORequest *)handle->device_req);
  737.         handle->device_req=NULL;
  738.     }
  739.     if (handle->device_port) {
  740.         LDeletePort(handle->device_port);
  741.         handle->device_port=NULL;
  742.     }
  743. }
  744.  
  745. void drive_motor(req,state)
  746. struct IOExtTD *req;
  747. int state;
  748. {
  749.     req->iotd_Req.io_Command=TD_MOTOR;
  750.     req->iotd_Req.io_Length=state;
  751.     DoIO((struct IORequest *)req);
  752. }
  753.  
  754. void show_sel_item(list)
  755. struct DOpusListView *list;
  756. {
  757.     while (list) {
  758.         if (list->itemselected<list->topitem ||
  759.             list->itemselected>(list->topitem+list->lines-1)) {
  760.             list->topitem=list->itemselected;
  761.             RefreshListView(list,1);
  762.         }
  763.         list=list->next;
  764.     }
  765. }
  766.